﻿using System;
using System.Collections.Generic;
using System.Text;
using DecodeInterface;
using System.Drawing;

namespace MotionDetect
{
    public class PointTrack : DecodeBitmap
    {
        protected override unsafe object[] OnDecode(byte* pIn, byte* pOut, System.Drawing.Size sizeIn, System.Drawing.Size sizeOut, params object[] state)
        {
            //int lenghtData = sizeIn.Width * sizeIn.Height * 3;
            //int width = sizeIn.Width * 3;
            //for (int y = width; y < lenghtData - width; y += width)
            //{
            //    for (int x = 3; x < width - 3; x += 3)
            //    {
            //        int index = y + x;
            //        int sum = 0;
            //        for (int j = -width; j <= width; j += width)
            //        {
            //            for (int i = -3; i <= 3; i += 3)
            //            {
            //                if (i == 0 && j == 0) continue;
            //                index = y + j + x + i;
            //                sum += pIn[index];
            //            }
            //        }
            //        pOut[index] = pOut[index + 1] = pOut[index + 2] = (byte)(sum >> 3);
            //    }
            //}

            return new object[] { };
        }

        //帧序列
        List<byte[][]> bIns = new List<byte[][]>();
        protected override object[] OnDecode(byte[][] bIn, byte[][] bOut, params object[] state)
        {
            //if (bIns.Count > 10) bIns.RemoveAt(0);
            //bIns.Add(bIn);
            //提取边界点（空间）（点）
            //提取闪烁点（时空）（点）

            //提取连续边界点集（空间）（线）
            //提取闪烁边界点集（时空）（线）

            //角点

            //提取颜色相近的点集（空间）（面）
            //提取颜色变化频率相近点集（时空）（面）

            //一帧图像构成二维空间
            //连续帧图像构成一维时间二维空间

            //在一帧图像中某一点点的边界性程度由其自身与周边点的差异性决定
            //在连续帧图像中某一点的闪烁性由其自身与该帧前后帧中该点的差异性决定
            //线的构成由连续边界性点组成

            //注意力：对某一特征的关注会加强该特征

            //非均匀采样
            int height = bIn.Length, width = bIn[0].Length;
            Point center = new Point(width / 6, height / 2);
            for (int y = 0; y < height; y++)
            {
                int spanY = Math.Abs(y - center.Y);

                for (int x = 0; x < width; x += 3)
                {
                    int spanX = Math.Abs(x / 3 - center.X);
                    int span = 5;
                    if (spanY >= 200 || spanX >= 200)
                    {
                        if (spanX % span != 0 || spanY % span != 0) continue;
                    }
                    else
                    {
                        span = Math.Max(spanX / 40 + 1, spanY / 40 + 1);
                        if (spanX % span != 0
                            || spanY % span != 0) continue;
                    }
                    
                    SetColor(bOut, x, y, bIn, x, y);
                }
            }

            //提取具有相同特征的区域
            //  区域即为一块独立性感知的部分
            //  具有静态和动态特征
            //  可以独立于图像存在
            //  可以抽象出来，即特征提取
            //  抽象不依赖于区域的大小，位置，有时候也不依赖于角度
            //  空间位置颜色的相对性，
            //提取灰度相近的区域

            //模糊
            //for (int y = 1; y < height - 1; y++)
            //{
            //    for (int x = 3; x < width - 3; x += 3)
            //    {
            //        int sum = 0;
            //        byte value = bIn[y][x];
            //        sum += bIn[y][x - 3];
            //        sum += value - bIn[y][x + 3];
            //        sum += bIn[y + 1][x];
            //        sum += value - bIn[y - 1][x];

            //        SetColor(bOut, x, y, (byte)(sum >> 2));
            //    }
            //}
            //for (int y = 0; y < height; y++)
            //{
            //    for (int x = 0; x < width; x += 3)
            //    {
            //        SetColor(bIn, x, y, bOut, x, y);
            //    }
            //}

            //for (int y = 0; y < height - 2; y++)
            //{
            //    for (int x = 6; x < width - 6; x += 3)
            //    {
            //        int sum1 = 0, sum2 = 0;
            //        byte value = bIn[y][x];

            //        sum1 = Math.Max(sum1, Math.Abs(value - bIn[y][x + 3]));
            //        sum1 = Math.Max(sum1, Math.Abs(value - bIn[y + 1][x]));
            //        sum1 = Math.Max(sum1, Math.Abs(value - bIn[y + 1][x + 3]));
            //        sum1 = Math.Max(sum1, Math.Abs(value - bIn[y + 1][x - 3]));

            //        sum2 = Math.Max(sum2, Math.Abs(value - bIn[y][x + 6]));
            //        sum2 = Math.Max(sum2, Math.Abs(value - bIn[y + 2][x]));
            //        sum2 = Math.Max(sum2, Math.Abs(value - bIn[y + 2][x + 6]));
            //        sum2 = Math.Max(sum2, Math.Abs(value - bIn[y + 2][x - 6]));

            //        if (sum1 > 50 || sum2 > 50)
            //        {
            //            SetColor(bOut, x, y, 255, 0, 0);
            //        }
            //        else if (sum1 < 20 || sum2 < 10)
            //        {
            //            //SetColor(bOut, x, y, 0, 255, 0);

            //            SetColor(bOut, x, y, value);

            //            SetColor(bOut, x + 3, y, value);
            //            SetColor(bOut, x, y + 1, value);
            //            SetColor(bOut, x + 3, y + 1, value);
            //            SetColor(bOut, x - 3, y + 1, value);

            //            SetColor(bOut, x + 6, y, value);
            //            SetColor(bOut, x, y + 2, value);
            //            SetColor(bOut, x + 6, y + 2, value);
            //            SetColor(bOut, x - 6, y + 2, value);
            //        }
            //        else
            //        {
            //            //SetColor(bOut, x, y, bIn, x, y);
            //            SetColor(bOut, x, y, 0, 255, 0);
            //        }
            //    }
            //}

            return base.OnDecode(bIn, bOut, state);
        }

        void SetColor(byte[][] bOut, int xOut, int yOut, byte b, byte g, byte r)
        {
            bOut[yOut][xOut] = b;
            bOut[yOut][xOut + 1] = g;
            bOut[yOut][xOut + 2] = r;
        }

        void SetColor(byte[][] bOut, int xOut, int yOut, byte grey)
        {
            bOut[yOut][xOut] = grey;
            bOut[yOut][xOut + 1] = grey;
            bOut[yOut][xOut + 2] = grey;
        }

        void SetColor(byte[][] bOut, int xOut, int yOut, byte[][] bIn, int xIn, int yIn)
        {
            bOut[yOut][xOut] = bIn[yIn][xIn];
            bOut[yOut][xOut + 1] = bIn[yIn][xIn + 1];
            bOut[yOut][xOut + 2] = bIn[yIn][xIn + 2];
        }

    }
}
